/*
 * boost_lock.hxx
 *
 *  Created on: 2023年6月14日
 *      Author: Dylan.Gao
 */

#ifndef DM_PLAT_SCADA_TEST_BOOST_LOCK_HXX_
#define DM_PLAT_SCADA_TEST_BOOST_LOCK_HXX_

#include <cxxtest/TestSuite.h>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <boost/interprocess/sync/upgradable_lock.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/named_upgradable_mutex.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/move/move.hpp>

using namespace boost::interprocess;

class TestBoostLocks:public CxxTest::TestSuite{
public:
	void testOperator() {
		named_upgradable_mutex::remove("test_boost_lock");
		named_upgradable_mutex mutex(open_or_create,"test_boost_lock");

		sharable_lock<named_upgradable_mutex> slock(mutex,try_to_lock);
		TSM_ASSERT("共享锁锁定",slock.owns());

		upgradable_lock<named_upgradable_mutex> ulock(boost::move(slock),try_to_lock);

		TSM_ASSERT("升级锁锁定",ulock.owns());

		scoped_lock<named_upgradable_mutex> lock(boost::move<>(ulock) );
		TSM_ASSERT("互斥锁锁定",lock.owns());
	}

	void testOperator2(){
		named_upgradable_mutex::remove("test_boost_lock");
		named_upgradable_mutex mutex(open_or_create,"test_boost_lock");

		sharable_lock<named_upgradable_mutex> slock(mutex);
		TSM_ASSERT("共享锁锁定",slock.owns());

		upgradable_lock<named_upgradable_mutex> ulock(mutex);
		TSM_ASSERT("升级锁锁定",ulock.owns());

		upgradable_lock<named_upgradable_mutex> ulock1(mutex,try_to_lock);
		TSM_ASSERT("升级锁重复锁定",!ulock1.owns());

		scoped_lock<named_upgradable_mutex> lock(mutex,try_to_lock);
		TSM_ASSERT("锁重复锁定",!lock.owns());

		sharable_lock<named_upgradable_mutex> slock2(mutex,try_to_lock);
		TSM_ASSERT("共享锁重复锁定",!lock.owns());
	}

	void testLockLayers(){
		named_upgradable_mutex::remove("test_boost_lock");
		named_upgradable_mutex mutex(open_or_create,"test_boost_lock");

		sharable_lock<named_upgradable_mutex> slock(mutex,try_to_lock);
		TSM_ASSERT("共享锁锁定",slock.owns());

		TSM_ASSERT("内部升级锁锁定",tryLockInner(slock));

		/**
		 * 通过锁转移后，原来的锁是不能再锁定的
		 */
		TSM_ASSERT("内部解锁后",!slock.owns());
	}

	bool tryLockInner( sharable_lock<named_upgradable_mutex>& slock ){
		upgradable_lock<named_upgradable_mutex> ulock( boost::move<>(slock),try_to_lock );
		return ulock.owns();
	}
};



#endif /* DM_PLAT_SCADA_TEST_BOOST_LOCK_HXX_ */
